package com.wiscamp.ninechapters.panels.infrastructure.repositories;


import com.wiscamp.ninechapters.panels.domain.entities.Parameter;
import com.wiscamp.ninechapters.panels.domain.repositories.ParameterRepository;
import com.wiscamp.ninechapters.panels.infrastructure.converters.ParameterConverter;
import com.wiscamp.ninechapters.panels.infrastructure.mappers.ParameterMapper;
import com.wiscamp.ninechapters.panels.infrastructure.mappers.ParameterViewMapper;
import com.wiscamp.ninechapters.panels.infrastructure.po.ParameterPO;
import com.wiscamp.ninechapters.panels.infrastructure.views.ParameterView;
import cube.ddd.aspect.HandleDataException;
import cube.ddd.common.query.PagedObjects;
import cube.ddd.common.query.PagedQuery;
import cube.ddd.utils.PersistenceUtils;
import org.springframework.stereotype.Repository;

import java.util.Collection;

@Repository
public class ParameterRepositoryImpl implements ParameterRepository {

    private final ParameterMapper parameterMapper;

    private final ParameterViewMapper parameterViewMapper;

    public ParameterRepositoryImpl(ParameterMapper parameterMapper, ParameterViewMapper parameterViewMapper) {
        this.parameterMapper = parameterMapper;
        this.parameterViewMapper = parameterViewMapper;
    }

    private ParameterPO getParameterPO(long parameterId) {
        return PersistenceUtils.findById(parameterId, parameterMapper::findById);
    }

    @HandleDataException
    public Parameter getParameter(long parameterId) {
        return PersistenceUtils.findEntityById(parameterId, parameterViewMapper::findById,
                ParameterConverter.Instance::toParameterByView);
    }

    @HandleDataException
    public Parameter getParameterByCode(long appId, String parameterCode) {
        return PersistenceUtils.getEntityByIdAndText(appId, parameterCode, parameterViewMapper::findByParameterCode,
                ParameterConverter.Instance::toParameterByView);
    }

    @HandleDataException
    public Collection<Parameter> getParametersByGroup(long appId, String parameterGroup) {
        return PersistenceUtils.getEntitiesByIdAndText(appId, parameterGroup, parameterViewMapper::findListByParameterGroup,
                ParameterConverter.Instance::toParameterByView);
    }

    @HandleDataException
    public Collection<Parameter> getParametersByName(long appId, String parameterName) {
        return PersistenceUtils.getEntitiesByIdAndText(appId, parameterName, parameterViewMapper::findListByParameterName,
                ParameterConverter.Instance::toParameterByView);
    }

    @HandleDataException
    public Collection<Parameter> getParametersByIds(Collection<Long> parameterIds) {
        return PersistenceUtils.getEntitiesByIds(parameterIds, parameterViewMapper::findAllById,
                ParameterConverter.Instance::toParameterByView);
    }

    @HandleDataException
    public PagedObjects<Parameter> getParametersByQuery(PagedQuery query) {
        PagedObjects<ParameterView> pagedObjects = PersistenceUtils.getPersistenceObjectsByQuery(query, parameterViewMapper::findAll);
        return PersistenceUtils.convertPagedObjects(pagedObjects, ParameterConverter.Instance::toParameterByView);
    }

    @HandleDataException
    public Parameter saveParameter(Parameter parameter) {
        if (parameter.getParameterId() <= 0) {
            return PersistenceUtils.createEntity(parameter, parameterMapper::saveAndFlush,
                    ParameterConverter.Instance::toParameterPO, ParameterConverter.Instance::toParameter);
        } else {
            var existedPO = getParameterPO(parameter.getParameterId());
            if (existedPO == null) existedPO = new ParameterPO();
            return PersistenceUtils.updateEntity(parameter, existedPO, parameterMapper::saveAndFlush,
                    ParameterConverter.Instance::toParameterPO, ParameterConverter.Instance::toParameter);
        }
    }

}
